package bocchi.general;

import com.badlogic.gdx.files.FileHandle;
import com.megacrit.cardcrawl.cards.AbstractCard;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Stream;

public class ResourcePath {
    public static final String RESOURCE = "bocchi/";

    public static final String IMAGE = RESOURCE + "image/";
    public static final String LOCALIZATION = RESOURCE + "localization/";
    public static final String DATA = RESOURCE + "data/";

    public static final String CARD = IMAGE + "card/";
    public static final String POWER = IMAGE + "power/";
    public static final String RELIC = IMAGE + "relic/";
    public static final String CHARACTER = IMAGE + "character/";
    public static final String ORB = CHARACTER + "orb/";

    public static final String ZHS = LOCALIZATION + "zhs/";
    public static final String ENG = LOCALIZATION + "eng/";

    public static final String KEYWORD = ZHS + "keyword.json";
    public static final String CARD_DATA = DATA + "card/";

    public static String card(String rawID) {
        return CARD + rawID + ".png";
    }

    public static String defaultCard(AbstractCard.CardType type) {
        return CARD + "default/" + type.toString().toLowerCase() + ".png";
    }

    public static List<String> list(String path) {
        try {
            String normalizedPath = path.endsWith("/") ? path : path + "/";

            ClassLoader classLoader = ResourcePath.class.getClassLoader();
            Enumeration<URL> resources = classLoader.getResources(normalizedPath);

            List<String> filePaths = new ArrayList<>();
            while (resources.hasMoreElements()) {
                URL resourceUrl = resources.nextElement();
                if (resourceUrl.getProtocol().equals("file")) {
                    filePaths.addAll(listFromFileSystem(resourceUrl, normalizedPath));
                } else if (resourceUrl.getProtocol().equals("jar")) {
                    filePaths.addAll(listFromJar(resourceUrl, normalizedPath));
                } else {
                    throw new IllegalArgumentException("Unsupported protocol: " + resourceUrl.getProtocol());
                }
            }
            return filePaths;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static List<String> listFromFileSystem(URL url, String path) throws IOException, URISyntaxException {
        List<String> filePaths = new ArrayList<>();
        Path dirPath = Paths.get(url.toURI());
        try (Stream<Path> stream = Files.walk(dirPath)) {
            stream.filter(Files::isRegularFile)
                    .forEach(file -> {
                        String fullPath = dirPath.relativize(file).toString();
                        filePaths.add(path + fullPath);
                    });
        }
        return filePaths;
    }

    private static List<String> listFromJar(URL url, String path) throws IOException {
        List<String> filePaths = new ArrayList<>();
        String jarPath = url.getPath().split("!")[0].replace("file:", "");
        try (JarFile jar = new JarFile(jarPath)) {
            Enumeration<JarEntry> entries = jar.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String entryName = entry.getName();
                if (entryName.startsWith(path) && !entry.isDirectory()) {
                    filePaths.add(entryName);
                }
            }
        }
        return filePaths;
    }
}
